﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

using ApplicationBoilerplate.DataProvider;

using Raven.Client.Document;

namespace MVCBootstrap.RavenDB {

	public class Repository<TEntity> : RepositoryBase<TEntity> where TEntity : class {
		private readonly ISession session;

		public Repository(ISession session) {
			this.session = session;
		}

		public override TEntity Create(TEntity newEntity) {
			this.session.GetSession().Store(newEntity);
			return newEntity;
		}

		public override TEntity Read(String id) {
			return this.session.GetSession().Load<TEntity>(id);
		}

		public override TEntity Read(Int32 id) {
			throw new NotImplementedException();
		}

		public override TEntity Read(Guid id) {
			throw new NotImplementedException();
		}

		public override TEntity Update(TEntity entity) {
			return entity;
		}

		public override void Delete(TEntity entity) {
			this.session.GetSession().Delete<TEntity>(entity);
		}

		public override void Delete(String id) {
			this.Delete(this.Read(id));
		}

		public override void Delete(Int32 id) {
			throw new NotImplementedException();
		}

		public override void Delete(Guid id) {
			throw new NotImplementedException();
		}

		public override IEnumerable<TEntity> ReadAll() {
			return this.session.GetSession().Query<TEntity>().ToList();
		}

		public override TEntity ReadOne(ISpecification<TEntity> spec) {
			return this.session.GetSession().Query<TEntity>().Where(spec.IsSatisfied).First();
		}

		public override TEntity ReadOne(Expression<Func<TEntity, Boolean>> criteria) {
			return this.session.GetSession().Query<TEntity>().Where(criteria).First();
		}

		public override IEnumerable<TEntity> ReadMany(ISpecification<TEntity> spec) {
			return this.session.GetSession().Query<TEntity>().Where(spec.IsSatisfied);
		}

		public override IEnumerable<TEntity> ReadMany(Expression<Func<TEntity, Boolean>> criteria) {
			return this.session.GetSession().Query<TEntity>().Where(criteria);
		}
	}
}